/**   
* @Title: HttpAesUtils.java
* @Package org.xaoyaoyao.cloud.common.utils
* @Description: TODO
* @author xaoyaoyao
* @date Feb 14, 2019 1:54:47 PM
* @version V1.0   
*/
package org.xaoyaoyao.cloud.common.utils;

import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @ClassName: HttpAesUtils
 * @Description: TODO
 * @author xaoyaoyao
 * @date Feb 14, 2019 1:54:47 PM
 * 
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class HttpAesUtils {

	private static final String CHAR_SET = "UTF-8";

	/**
	 * @Title: encrypt
	 * @Description: 加密
	 * @param contentParam
	 *            需要加密的内容
	 * @param keyParam
	 *            加密密码
	 * @param md5Key
	 *            是否对key进行md5加密
	 * @param ivParam
	 *            加密向量
	 * @throws Exception
	 * @return String 加密后的字节数据
	 */
	public static String encrypt(String contentParam, String keyParam, boolean md5Key, String ivParam) throws Exception {
		try {
			byte[] content = contentParam.getBytes(CHAR_SET);
			byte[] key = keyParam.getBytes(CHAR_SET);
			byte[] iv = ivParam.getBytes(CHAR_SET);
			if (md5Key) {
				MessageDigest md = MessageDigest.getInstance("MD5");
				key = md.digest(key);
			}
			SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
			// "算法/模式/补码方式"
			Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding");
			// 使用CBC模式, 需要一个向量iv, 可增加加密算法的强度
			IvParameterSpec ivps = new IvParameterSpec(iv);
			cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivps);
			byte[] bytes = cipher.doFinal(content);
			return new BASE64Encoder().encode(bytes);
		} catch (Exception ex) {
			log.error("加密密码失败", ex);
			throw new Exception("加密失败");
		}
	}

	/**
	 * @Title: decrypt
	 * @Description: 解密
	 * @param contentParam
	 *            需要加密的内容
	 * @param keyParam
	 *            加密密码
	 * @param md5Key
	 *            是否对key进行md5加密
	 * @param ivParam
	 *            加密向量
	 * @return String
	 * @throws Exception
	 */
	public static String decrypt(String contentParam, String keyParam, boolean md5Key, String ivParam) throws Exception {
		try {
			if (StringUtils.isNull(contentParam, keyParam, md5Key, ivParam)) {
				return "";
			}
			byte[] content = new BASE64Decoder().decodeBuffer(contentParam);
			byte[] key = keyParam.getBytes(CHAR_SET);
			byte[] iv = ivParam.getBytes(CHAR_SET);
			if (md5Key) {
				MessageDigest md = MessageDigest.getInstance("MD5");
				key = md.digest(key);
			}
			SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
			// "算法/模式/补码方式"
			Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding");
			// 使用CBC模式, 需要一个向量iv, 可增加加密算法的强度
			IvParameterSpec ivps = new IvParameterSpec(iv);
			cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivps);
			byte[] bytes = cipher.doFinal(content);
			return new String(bytes, CHAR_SET);
		} catch (Exception ex) {
			log.error("解密密码失败", ex);
			throw new Exception("解密失败");
		}
	}

}
